#ifndef __UART_FINGER_H__
#define __UART_FINGER_H__

#include "stdint.h"

/* FINGER组件的NV大小 */
#define FINGER_NV_SIZE (10) // 目前实际只用到2 Byte
/* NV FINGER组件初始化标识*/
#define FINGER_NV_INIT_FLAG 0xFA
/* 定时时间 */
#define FINGER_PROCESSOR_TIME 50
/* 添加指纹需要按下总次数 */
#define FINGER_ADD_TIMES 5//8

// 组包数据
#define FINGER_RB_RXBUF_LENGTH 64
#define PROTOCOL_PACKET_STX 0XEF01
#define PROTOCOL_IC_ADDR 0XFFFFFFFF

/**********************sensor cmd*******************************/
#define PS_GETIMAGE         0X01 // 获取图像
#define PS_GENCHAR          0X02 // 生成特征
#define PS_SEARCH           0X04 // 验证指纹
#define PS_REG_MODEL        0X05 // 合并特征
#define PS_STORECHAR        0X06 // 存储模板
#define PS_DELETCHAR        0X0C // 删除单个指纹
#define PS_EMPTY            0X0D // 删除全部指纹
// #define PS_READINFPAGE      0X16 // 读取flash信息页
#define PS_GetENROLLIMAGE   0X29 // 获取图像
#define PS_CANCEL           0X30 // 取消指令
#define PS_SLEEP            0X33 // 睡眠指令
#define PS_HAND_SHAKE       0X35 // 握手指令
#define PS_READ_VERSION     0XAF // 读取版本号指令

/**********************指令回调*******************************/
// 确认码
#define ACK_SUCCESS     0x00 // 成功
#define ACK_FAIL        0x01 // 失败
#define ACK_NO_FINGER   0x02 // 无手指
#define ACK_NO_LEAVE    0x17 // 没离开手指
#define ACK_NULL        0x24 // 指纹库为空
#define ACK_TIMEOUT     0x26 // 超时

// 应答包参数
#define FINGER_LEGAL        0x00 // 指纹合法性
#define FINGER_IMAGE        0x01 // 获取图像
#define FINGER_FEATURE      0x02 // 生成特征
#define FINGER_LEAVE        0x03 // 手指离开
#define FINGER_MERGE        0x04 // 合并模板
#define FINGER_AUTOENROLL   0x05 // 注册验证
#define FINGER_COMPARE      0x05 // 指纹比对
#define FINGER_SAVE         0x06 // 存储模板

/**********************模组返回包类型*******************************/
#define FINGER_PACK_CMD    0X01 // 命令包
#define FINGER_PACK_DATA   0X02 // 数据包
#define FINGER_PACK_ACK    0X07 // 应答包
#define FINGER_PACK_LAST   0X08 // 数据包最后一包

/**********************LED CONTROL*******************************/
#define PS_CONTROL_LED     0X3C // LED控制指令

typedef void (*Finger_send_cb_fun_t)(uint8_t *ackpacket); //发送回调类型

#pragma pack(1)
/* 协议头结构 */
typedef struct
{
    uint16_t stx;     //数据头
    uint32_t ic_addr; //芯片地址
    uint8_t pack_flg; //包标识
    uint16_t len;     //数据长度
} ProtocolDataHead_stu_t;

/* 命令包结构 */
typedef struct
{
    ProtocolDataHead_stu_t head;
    uint8_t cmd;
    uint8_t dataBuf[]; //数据域长度不定 最后两字节是校验和
} CmdPacket_stu_t;

/* 应答包结构 */
typedef struct
{
    ProtocolDataHead_stu_t head;
    uint8_t confrim_code; //确认码
    uint8_t dataBuf[];    //数据域长度不定 最后两字节是校验和
} AckPacket_stu_t;

/* 数据包结构 */
typedef struct
{
    ProtocolDataHead_stu_t head;
    uint8_t dataBuf[];    //数据域长度不定 最后两字节是校验和
} DataPacket_stu_t;

// tx命令包结构
typedef struct
{
    uint8_t buffer[MAX_PACKAGE_LEN]; //发送缓存
    uint16_t len;                    //数据长度
    uint32_t acktimeout;             //等待ACK的超时时间（为0：不需要ACK）
    Finger_send_cb_fun_t cb;         //发送命令回调（为NULL：不需要回调）
} uart_txcmd_packet_stu_t;

/* 命令包发送状态信息 */
static struct
{
    uart_txcmd_packet_stu_t data; //数据
    uint8_t cmd;                  //发送的命令
    uint32_t timeStamp;           //最后一次发送的时间戳
    uint8_t cnt;                  //发送次数（可能重发）
    enum
    {                    //当前发送的状态
        TX_STA_IDLE,     //空闲
        TX_STA_WAIT_ACK, //等待模块回复应答包
    } status;
    RingBufferHandle_t tbHandle;
} CmdPacketTxInfo;

/* 命令包接收状态信息：记录蓝牙和Uart两个设备的发送状态 */
static struct
{
    uint8_t protocolBuf[MAX_PACKAGE_LEN]; //协议解析缓存
    uint8_t protocolCount;                //协议解析计数变量
    RingBufferHandle_t rbHandle;
    ExtendKdsMsg_t *rx_msg;
    uint32_t timeStamp;           //接收应答包的时间戳
    enum
    {
        RX_STA_IDLE,     //空闲
        RX_STA_SEND_ACK, //正在发送多包ACK
    } status;
} CmdPacketRxInfo;

/********************数据包定义**************************/
/* 命令包和回调关联结构体 */
typedef struct
{
    uint8_t cmd;
    Finger_send_cb_fun_t callback;
} AckPakcet_ProecssFun_t;

// 指纹运行状态数据
typedef struct
{
    Finger_WorkMode_enum_t mode; // 工作模式
    uint8_t enroll_num;          // 注册次数

} Finger_Status_Data_stu_t;

typedef struct
{
    uint8_t mode;        // 工作模式
    uint8_t startColor; // 开始颜色
    uint8_t endColor;   // 结束颜色
    uint8_t times;       // 循环次数  --- 仅支持呼吸灯和闪烁灯，0为无限
} Finger_Led_Control_stu_t;

#pragma pack()


void PS_Search_cb(uint8_t *ackpacket);
void Finger_GenChar_cb(uint8_t *ackpacket);
void Finger_PsHandShake_cb(uint8_t *ackpacket);
void Finger_PsCancel_cb(uint8_t *ackpacket);
void Finger_RegModel_cb(uint8_t *ackpacket);
void Finger_StoreChar_cb(uint8_t *ackpacket);
void Finger_DeleteModel_cb(uint8_t *ackpacket);
void Finger_PsSleep_cb(uint8_t *ackpacket);
void Finger_GetImage_cb(uint8_t *ackpacket);
void FINGER_ReadVersion_cb(uint8_t *ackpacket);
void Finger_wait_acktimeout(void);
void Finger_DetectNoFinger_cb(void);

AckPakcet_ProecssFun_t Ack_HandleFun[] =
    {
        {PS_GETIMAGE, Finger_GetImage_cb},
        {PS_GENCHAR, Finger_GenChar_cb},
        {PS_GetENROLLIMAGE, Finger_GetImage_cb},
        {PS_SEARCH, PS_Search_cb},
        {PS_REG_MODEL, Finger_RegModel_cb},
        {PS_STORECHAR, Finger_StoreChar_cb},
        {PS_DELETCHAR, Finger_DeleteModel_cb},
        {PS_EMPTY, Finger_DeleteModel_cb},
        {PS_HAND_SHAKE, Finger_PsHandShake_cb},
        {PS_CANCEL, Finger_PsCancel_cb},
        {PS_SLEEP, Finger_PsSleep_cb},
        // {PS_READINFPAGE, Finger_PsVersion_cb},
        {PS_READ_VERSION, FINGER_ReadVersion_cb},
};

#define ACK_HANDLER_LENGH (sizeof(Ack_HandleFun) / sizeof(AckPakcet_ProecssFun_t))
#endif /* __UART_FINGER_H__ */
